/**
 * 字符类型验证规则
 */
import { fromBytes } from '../../numbers';
import { ValidationResult } from '../types';

/**
 * 字符类型验证规则选项接口
 * @property {('chinese' | 'english' | 'alphanumeric' | 'numeric')} type - 字符类型
 *  - `chinese`: 中文
 *  - `english`: 英文
 *  - `alphanumeric`: 字母数字
 *  - `numeric`: 数字
 * @property {boolean} [allowSpaces] - 是否允许空格
 * @property {string} [allowChars] - 额外允许的字符
 */
export interface CharTypeValidationOptions {
    /**
     * 字符类型
     *  - `chinese`: 中文
     *  - `english`: 英文
     *  - `alphanumeric`: 字母数字
     *  - `numeric`: 数字
     */
    type: 'chinese' | 'english' | 'alphanumeric' | 'numeric';

    /**
     * 是否允许空格
     */
    allowSpaces?: boolean;

    /**
     * 额外允许的字符
     */
    allowChars?: string;
}

/**
 * 整数/浮点数验证规则选项接口
 * @property {('number' | 'integer' | 'float')} [type] - 数字类型
 *  - `number`: 数字
 *  - `integer`: 整数
 *  - `float`: 浮点数
 * @property {number} [minDecimals] - 允许的最小小数位数（可选，仅对float类型有效）
 * @property {number} [maxDecimals] - 允许的最大小数位数（可选，仅对float类型有效）
 */
export interface NumberValidationOptions {
    /**
     * 数字类型
     *  - `number`: 数字
     *  - `integer`: 整数
     *  - `float`: 浮点数
     */
    type?: 'number' | 'integer' | 'float';

    /**
     * 允许的最小小数位数（可选，仅对float类型有效）
     */
    minDecimals?: number;

    /**
     * 允许的最大小数位数（可选，仅对float类型有效）
     */
    maxDecimals?: number;
}

/**
 * 文件验证规则选项接口
 * @property {string[]} [allowedTypes] 允许的文件类型列表，如['image/jpeg', 'image/png']（可选）
 * @property {string[]} [allowedExtensions] 允许的文件扩展名列表，如['jpg', 'png']（可选）
 * @property {number} [minSize] 最小文件大小（字节，可选）
 * @property {number} [maxSize] 最大文件大小（字节，可选）
 */
export interface FileValidationOptions {
    /**
     * 允许的文件类型列表，如['image/jpeg', 'image/png']（可选）
     */
    allowedTypes?: string[];

    /**
     * 允许的文件扩展名列表，如['jpg', 'png']（可选）
     */
    allowedExtensions?: string[];

    /**
     * 最小文件大小（字节，可选）
     */
    minSize?: number;

    /**
     * 最大文件大小（字节，可选）
     */
    maxSize?: number;
}

/**
 * 字符类型验证规则
 * 
 * @param {any} value - 要验证的值
 * @param {CharTypeValidationOptions} options - 字符类型验证选项
 * @param {string} [options.type] - 字符类型
 * @param {boolean} [options.allowSpaces] - 是否允许空格
 * @param {string} [options.allowChars] - 额外允许的字符
 * @returns {ValidationResult} 验证结果
 * 
 * @example
 * // 验证汉字
 * const result1 = validateCharType('你好', { type: 'chinese' });
 * console.log(result1); // { valid: true, message: undefined }
 * 
 * // 验证英文和数字
 * const result2 = validateCharType('abc123', { type: 'alphanumeric' });
 * console.log(result2); // { valid: true, message: undefined }
 * 
 * // 使用validateRule
 * const ruleResult = validateRule('abc123', { type: 'charType', options: { type: 'english' } });
 * console.log(ruleResult); // { valid: false, message: '请输入英文' }
 */
export function validateCharType(value: any, options: CharTypeValidationOptions): ValidationResult {
    if (value === undefined || value === null || value === '') {
        return {
            valid: false,
            message: '请输入文本'
        };
    }

    const text = String(value);
    let pattern: RegExp;
    let typeName = '';

    switch (options.type) {
        case 'chinese':
            pattern = /^[\u4e00-\u9fa5]+$/;
            typeName = '汉字';
            break;
        case 'english':
            pattern = /^[a-zA-Z]+$/;
            typeName = '英文';
            break;
        case 'alphanumeric':
            pattern = /^[a-zA-Z0-9]+$/;
            typeName = '英文数字';
            break;
        case 'numeric':
            pattern = /^[0-9]+$/;
            typeName = '数字';
            break;
        default:
            return {
                valid: false,
                message: '不支持的字符类型'
            };
    }

    // 处理空格选项
    let testText = text;
    if (options.allowSpaces) {
        testText = text.replace(/\s/g, '');
    }

    // 处理额外允许的字符
    if (options.allowChars && options.allowChars.length > 0) {
        const escapedChars = options.allowChars.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        pattern = new RegExp(`^[${options.type === 'chinese' ? '\\u4e00-\\u9fa5' : pattern.source.slice(1, -1)}${escapedChars}]+$`);
    }

    const isValid = pattern.test(testText);
    return {
        valid: isValid,
        message: isValid ? undefined : `请输入${typeName}`
    };
}

/**
 * 整数/浮点数验证规则
 * 
 * @param {any} value - 要验证的值
 * @param {NumberValidationOptions} options - 数字类型验证选项
 * @property {('number' | 'integer' | 'float')} [options.type] - 数字类型
 *  - `number`: 数字
 *  - `integer`: 整数
 *  - `float`: 浮点数
 * @property {number} [options.minDecimals] - 允许的最小小数位数（可选，仅对float类型有效）
 * @property {number} [options.maxDecimals] - 允许的最大小数位数（可选，仅对float类型有效）
 * @returns {ValidationResult} 验证结果
 * 
 * @example
 * // 验证整数
 * const result1 = validateNumber(123, { type: 'integer' });
 * console.log(result1); // { valid: true, message: undefined }
 * 
 * // 验证浮点数（最多2位小数）
 * const result2 = validateNumber(123.45, { type: 'float', maxDecimals: 2 });
 * console.log(result2); // { valid: true, message: undefined }
 * 
 * // 使用validateRule
 * const ruleResult = validateRule(123.456, { type: 'numberType', options: { type: 'float', maxDecimals: 2 } });
 * console.log(ruleResult); // { valid: false, message: '请输入最多2位小数的浮点数' }
 */
export function validateNumber(value: any, options?: Partial<NumberValidationOptions>): ValidationResult {
    // 设置默认选项，type默认为number
    const defaultOptions: NumberValidationOptions = {
        type: 'number',
        ...options
    };
    
    if (value === undefined || value === null || value === '') {
        return {
            valid: false,
            message: '请输入数值'
        };
    }

    const numValue = Number(value);
    if (isNaN(numValue)) {
        return {
            valid: false,
            message: '请输入有效的数值'
        };
    }

    let isValid = true;
    let message: string | undefined;

    // number 类型是最宽松的数字验证，只要是有效数值即可
    if (defaultOptions.type === 'number') {
        // 已经通过了前面的基本数值有效性检查
        isValid = true;
    } else if (defaultOptions.type === 'integer') {
        isValid = Number.isInteger(numValue);
        if (!isValid) {
            message = '请输入整数';
        }
    } else if (defaultOptions.type === 'float') {
        // 检查是否为浮点数
        const valueString = String(value);
        const decimalPart = valueString.split('.')[1];

        // 检查最小小数位数
        if (defaultOptions.minDecimals !== undefined && decimalPart && decimalPart.length < defaultOptions.minDecimals) {
            isValid = false;
            message = `请输入至少${defaultOptions.minDecimals}位小数的浮点数`;
        }

        // 检查最大小数位数
        if (isValid && defaultOptions.maxDecimals !== undefined && decimalPart && decimalPart.length > defaultOptions.maxDecimals) {
            isValid = false;
            message = `请输入最多${defaultOptions.maxDecimals}位小数的浮点数`;
        }
    }

    return {
        valid: isValid,
        message
    };
}



/**
 * 文件验证规则
 * 
 * @param {any} value - 要验证的值（File对象或FileList）
 * @param {FileValidationOptions} [options] - 文件验证选项
 *  - `allowedTypes` (string[]): 允许的文件类型列表，如['image/jpeg', 'image/png']（可选）
 *  - `allowedExtensions` (string[]): 允许的文件扩展名列表，如['jpg', 'png']（可选）
 *  - `minSize` (number): 最小文件大小（字节，可选）
 *  - `maxSize` (number): 最大文件大小（字节，可选）
 * @returns {ValidationResult} 验证结果
 * 
 * @example
 * // 验证文件类型和大小
 * const result1 = validateFile(file, {
 *   allowedTypes: ['image/jpeg', 'image/png'],
 *   maxSize: 5 * 1024 * 1024 // 5MB
 * });
 * console.log(result1); // { valid: true, message: undefined }
 * 
 * // 使用validateRule
 * const ruleResult = validateRule(largeFile, { 
 *   type: 'file', 
 *   options: { maxSize: 1 * 1024 * 1024 } 
 * });
 * console.log(ruleResult); // { valid: false, message: '文件大小不能超过1MB' }
 */
export function validateFile(value: any, options: FileValidationOptions = {}): ValidationResult {
    if (value === undefined || value === null) {
        return {
            valid: false,
            message: '请选择文件'
        };
    }

    // 处理FileList（多个文件）
    if (value instanceof FileList) {
        // 这里只验证第一个文件，如果需要验证所有文件可以扩展
        if (value.length === 0) {
            return {
                valid: false,
                message: '请选择文件'
            };
        }
        value = value[0];
    }

    // 检查是否为File对象
    if (!(value instanceof File)) {
        return {
            valid: false,
            message: '请选择有效的文件'
        };
    }

    const file = value;

    // 检查文件类型
    if (options.allowedTypes && options.allowedTypes.length > 0) {
        if (!options.allowedTypes.includes(file.type)) {
            return {
                valid: false,
                message: `不支持的文件类型，仅允许${options.allowedTypes.join('、')}`
            };
        }
    }

    // 检查文件扩展名
    if (options.allowedExtensions && options.allowedExtensions.length > 0) {
        const fileName = file.name.toLowerCase();
        const fileExt = fileName.split('.').pop() || '';
        const isValidExt = options.allowedExtensions.some(ext => fileExt === ext.toLowerCase());
        if (!isValidExt) {
            return {
                valid: false,
                message: `不支持的文件扩展名，仅允许${options.allowedExtensions.join('、')}`
            };
        }
    }

    // 检查文件大小（最小值）
    if (options.minSize !== undefined && file.size < options.minSize) {
        return {
            valid: false,
            message: `文件大小不能小于${fromBytes(options.minSize)}`
        };
    }

    // 检查文件大小（最大值）
    if (options.maxSize !== undefined && file.size > options.maxSize) {
        return {
            valid: false,
            message: `文件大小不能超过${fromBytes(options.maxSize)}`
        };
    }

    return {
        valid: true,
        message: undefined
    };
}